﻿
using System.Collections.Generic;
using PerfAssist.Common.Editor;
using PerfAssist.Common.usmooth.Client;
using PerfAssist.Common.usmooth.Common;
#if UNITY_EDITOR
using UnityEditor;

#endif

namespace PerfAssist.MemoryProfilerAdvanced.Editor
{
    public class RequestStackInfosSummary
    {
#if UNITY_EDITOR
        [MenuItem(PAEditorConst.DevCommandPath + "/RequestStackInfosSummary")]
        private static void RequestStackSummary()
        {
#if UNITY_EDITOR
            if (NetManager.Instance == null)
                return;
            var w = EditorWindow.GetWindow<MemoryProfilerWindow>("MemoryProfilerWindow");
            if (w.GetType().Name == "MemoryProfilerWindow")
            {
                if (w.UnpackedCrawl == null)
                    return;

                var categoryDict = new Dictionary<string, List<stackParamater>>();

                foreach (var trackCategory in SceneGraphExtractor.MemCategories)
                    if (!categoryDict.ContainsKey(trackCategory))
                        categoryDict.Add(trackCategory, new List<stackParamater>());

                foreach (var obj in w.UnpackedCrawl.nativeObjects)
                    if (categoryDict.ContainsKey(obj.className))
                    {
                        List<stackParamater> list;
                        categoryDict.TryGetValue(obj.className, out list);
                        var info = new stackParamater();
                        info.InstanceID = obj.instanceID;
                        info.Size = obj.size;
                        list.Add(info);
                    }

                var cmd = new UsCmd();
                cmd.WriteInt16((short) eNetCmd.CL_RequestStackSummary);
                cmd.WriteString("begin");
                NetManager.Instance.Send(cmd);

                var passCountPerCmd = 500;
                foreach (var categoryPair in categoryDict)
                {
                    var count = categoryPair.Value.Count;
                    var times = count / passCountPerCmd;
                    var residue = count % passCountPerCmd;

                    for (var i = 0; i < times; i++)
                    {
                        cmd = new UsCmd();
                        cmd.WriteInt16((short) eNetCmd.CL_RequestStackSummary);
                        cmd.WriteString(categoryPair.Key);
                        cmd.WriteInt32(passCountPerCmd);
                        for (var j = i * passCountPerCmd; j < (i + 1) * passCountPerCmd; j++)
                        {
                            var info = categoryPair.Value[j];
                            cmd.WriteInt32(info.InstanceID);
                            cmd.WriteInt32(info.Size);
                        }

                        NetManager.Instance.Send(cmd);
                    }

                    if (residue > 0)
                    {
                        cmd = new UsCmd();
                        cmd.WriteInt16((short) eNetCmd.CL_RequestStackSummary);
                        cmd.WriteString(categoryPair.Key);
                        cmd.WriteInt32(residue);
                        for (var i = 0; i < residue; i++)
                        {
                            var info = categoryPair.Value[times * passCountPerCmd + i];
                            cmd.WriteInt32(info.InstanceID);
                            cmd.WriteInt32(info.Size);
                        }

                        NetManager.Instance.Send(cmd);
                    }
                }

                cmd = new UsCmd();
                cmd.WriteInt16((short) eNetCmd.CL_RequestStackSummary);
                cmd.WriteString("end");
                cmd.WriteInt32(categoryDict.Count);
                foreach (var categoryPair in categoryDict)
                {
                    cmd.WriteString(categoryPair.Key);
                    cmd.WriteInt32(categoryPair.Value.Count);
                    var categoryTotalSize = 0;
                    foreach (var info in categoryPair.Value) categoryTotalSize += info.Size;
                    cmd.WriteInt32(categoryTotalSize);
                }

                NetManager.Instance.Send(cmd);
            }
#endif
        }
#endif
        private class stackParamater
        {
            public int InstanceID { get; set; }

            public int Size { get; set; }
        }
    }
}